package com.speeda.pda.print.bluetooth;

import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Set;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;

import com.lvrenyang.pos.Cmd;
import com.lvrenyang.utils.DataUtils;

import android.app.Service;
import android.com.speeda.pda.print.bluetooth.Global;
import android.com.speeda.pda.print.bluetooth.WorkService;

import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.com.speeda.pda.print.bluetooth.WorkThread;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;

public class PrintPlugin extends CordovaPlugin {

	private ProgressDialog dialog;
	private static Handler mHandler = null;

	private static int nBarcodetype, nStartOrgx, nBarcodeWidth = 1, nBarcodeHeight = 3, nBarcodeFontType,
			nBarcodeFontPosition = 2;

	private Button btnPrint, btnConn, btnpo;
 

	private BluetoothAdapter btAdapt = null;
	private BluetoothSocket btSocket = null;

	Boolean bConnect = false;
	String strName = null;
	String strAddress = null;

	private static
	boolean isConnectioned = false;

	public static WorkService workService;

	private static String TAG = "BTPrinter Plugin";

	@Override
	public void onStart(){
		//final Activity mActivity = cordova.getActivity();
		//Intent intent = new Intent(mActivity, WorkService.class);
		//mActivity.startService(intent);
	}

	@Override
	public void onDestroy(){
		if(null != workService){
			workService.onDestroy();
		}
	}
	
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {

		if(null == workService){
			workService = new WorkService();
			workService.onCreate();
			workService.onStartCommand(cordova.getActivity().getIntent(),0,0);

			//Intent intent = new Intent(cordova.getActivity(), WorkService.class);
			//cordova.getActivity().startService(intent);
			//workService.startService(intent);
			mHandler = new MHandler(cordova.getActivity());
			WorkService.addHandler(mHandler);
		}


		if (null == WorkService.workThread) {



			// getBoundDevices();

			//dialog = new ProgressDialog(cordova.getActivity());
			//mHandler = new MHandler(cordova.getActivity());
			//WorkService.addHandler(mHandler);
		}




        if("conn".equals(action)){
            connectionBT(args.getString(0));
        }

        if("printText".equals(action)){
            printText(args.getString(0));
        }

		if("printTextV2".equals(action)){
			printTextV2(args.getString(0), args.getInt(1), args.getInt(2));
		}

		if("printPic".equals(action)){
			printPic(args.getString(0));
		}

        if("printBarcode".equals(action)){
            printCode(args.getString(0));
        }
        
        if("printQRCode".equals(action)){
            printQRCode(args.getString(0));
        }

		if("getBoundDevices".equals(action)){
			this.getBoundDevices(args,callbackContext);
		}

        return true;
    }

	
	//
	

	public void printText(String ptext) {

		int tryNum = 0;

		while (!WorkService.workThread.isConnected()) {
			tryNum++;
			if (tryNum > 6)
				break;
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (WorkService.workThread.isConnected()) {

			String text = ptext;// + "\r\n\r\n\r\n"; // 加三行换行，避免走纸
			byte header[] = null;
			byte strbuf[] = null;

			// 设置UTF8编码
			// Android手机默认也是UTF8编码
			header = new byte[] { 0x1b, 0x40, 0x1c, 0x26, 0x1b, 0x39, 0x01 };
			try {
				strbuf = text.getBytes("UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			byte buffer[] = DataUtils.byteArraysToBytes(new byte[][] { header, strbuf });
			Bundle data = new Bundle();
			data.putByteArray(Global.BYTESPARA1, buffer);
			data.putInt(Global.INTPARA1, 0);
			data.putInt(Global.INTPARA2, buffer.length);
			WorkService.workThread.handleCmd(Global.CMD_POS_WRITE, data);
		} else {
			Toast.makeText(cordova.getActivity(), Global.toast_notconnect, Toast.LENGTH_SHORT)
					.show();
		}
	}

	public void printTextV2(String text, int isBig,int isBold) {

		if (WorkService.workThread.isConnected()) {

			String encoding = "GBK";
			int charset = 15;
			int codepage = 255;

			Bundle dataCP = new Bundle();
			Bundle dataAlign = new Bundle();
			Bundle dataRightSpace = new Bundle();
			Bundle dataLineHeight = new Bundle();
			Bundle dataTextOut = new Bundle();
			Bundle dataWrite = new Bundle();
			dataCP.putInt(Global.INTPARA1, charset);
			dataCP.putInt(Global.INTPARA2, codepage);
			dataAlign.putInt(Global.INTPARA1, 0); //align
			dataRightSpace.putInt(Global.INTPARA1, 0);
			dataLineHeight.putInt(Global.INTPARA1, 0);


			dataTextOut.putString(Global.STRPARA1, text);
			dataTextOut.putString(Global.STRPARA2, encoding);
			dataTextOut.putInt(Global.INTPARA1, 0);
			dataTextOut.putInt(Global.INTPARA2, (isBig == 1 ? 1 : 0)); // ScaleTimesWidth
			dataTextOut.putInt(Global.INTPARA3, (isBig == 1 ? 1 : 0)); // ScaleTimesHeight
			dataTextOut.putInt(Global.INTPARA4, 0); // FontSize

			int nFontStyle = Cmd.Constant.FONTSTYLE_NORMAL; // FontStyle
			if(isBold > 0) nFontStyle = Cmd.Constant.FONTSTYLE_BOLD;

			dataTextOut.putInt(Global.INTPARA5, nFontStyle);

			//byte[] addBytes = new byte[0];
			//dataWrite.putByteArray(Global.BYTESPARA1, addBytes);
			//dataWrite.putInt(Global.INTPARA1, 0);
			//dataWrite.putInt(Global.INTPARA2, addBytes.length);

			text = text + "\r\n\r\n\r\n"; // 加三行换行，避免走纸
			byte header[] = null;
			byte strbuf[] = null;

			// 设置UTF8编码
			// Android手机默认也是UTF8编码
			header = new byte[] { 0x1b, 0x40, 0x1c, 0x26, 0x1b, 0x39, 0x01 };
			try {
				strbuf = text.getBytes("UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			byte buffer[] = DataUtils.byteArraysToBytes(new byte[][] { header, strbuf });
			Bundle data = new Bundle();
			data.putByteArray(Global.BYTESPARA1, buffer);
			data.putInt(Global.INTPARA1, 0);
			data.putInt(Global.INTPARA2, buffer.length);

			WorkService.workThread.handleCmd(Global.CMD_POS_SETCHARSETANDCODEPAGE, dataCP);
			WorkService.workThread.handleCmd(Global.CMD_POS_SALIGN, dataAlign);
			WorkService.workThread.handleCmd(Global.CMD_POS_SETRIGHTSPACE, dataRightSpace);
			WorkService.workThread.handleCmd(Global.CMD_POS_SETLINEHEIGHT, dataLineHeight);
			WorkService.workThread.handleCmd(Global.CMD_POS_STEXTOUT, dataTextOut);
			//WorkService.workThread.handleCmd(Global.CMD_POS_WRITE, data);
			
		}else{
			Toast.makeText(cordova.getActivity(), Global.toast_notconnect, Toast.LENGTH_SHORT).show();
		}
	}

	public void printPic(String picUrl){
		Bitmap mBitmap = this.downloadBitMap(picUrl);

		int nPaperWidth = 384;

		if (mBitmap != null) {
			if (WorkService.workThread.isConnected()) {
				Bundle alignData = new Bundle();
				alignData.putInt(Global.INTPARA1, 1);
				WorkService.workThread.handleCmd(Global.CMD_POS_SALIGN, alignData);

				Bundle data = new Bundle();
				//data.putParcelable(Global.OBJECT1, mBitmap);
				data.putParcelable(Global.PARCE1, mBitmap);
				data.putInt(Global.INTPARA1, nPaperWidth);
				data.putInt(Global.INTPARA2, 0);
				WorkService.workThread.handleCmd(
						Global.CMD_POS_PRINTPICTURE, data);
			} else {
				Toast.makeText(cordova.getActivity(), Global.toast_notconnect, Toast.LENGTH_SHORT).show();
			}
		}
	}

	public Bitmap downloadBitMap(String url) {
		//
		URL myFileUrl = null;
		Bitmap bitmap = null;
		try {
			myFileUrl = new URL(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			HttpURLConnection conn = (HttpURLConnection) myFileUrl
					.openConnection();
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();
			bitmap = BitmapFactory.decodeStream(is);
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
			Log.e(TAG,"Picture Path is error : " + e.getMessage());
		}
		return bitmap;
	}

	public void printCode(String code) {
		String strBarcode = code;
		if (strBarcode.length() == 0)
			return;
		int nOrgx = nStartOrgx * 12;
		int nType = Cmd.Constant.BARCODE_TYPE_UPC_A + nBarcodetype;
		int nWidthX = nBarcodeWidth + 2;
		int nHeight = (nBarcodeHeight + 1) * 24;
		int nHriFontType = nBarcodeFontType;
		int nHriFontPosition = nBarcodeFontPosition;

		int tryNum = 0;

		while (!WorkService.workThread.isConnected()) {
			tryNum++;
			if (tryNum > 6)
				break;
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (WorkService.workThread.isConnected()) {

			Bundle data = new Bundle();
			data.putString(Global.STRPARA1, strBarcode);
			data.putInt(Global.INTPARA1, nOrgx);
			data.putInt(Global.INTPARA2, nType);
			data.putInt(Global.INTPARA3, nWidthX);
			data.putInt(Global.INTPARA4, nHeight);
			data.putInt(Global.INTPARA5, nHriFontType);
			data.putInt(Global.INTPARA6, nHriFontPosition);
			WorkService.workThread
					.handleCmd(Global.CMD_POS_SETBARCODE, data);
		} else {
			Toast.makeText(cordova.getActivity(), Global.toast_notconnect, Toast.LENGTH_SHORT)
					.show();
		}
	}
	
	public void printQRCode(String code){
		String strQrcode = code;
		if (strQrcode.length() == 0)
			return;
		int nWidthX = 5;
		int necl = 2;
		if (WorkService.workThread.isConnected()) {
			Bundle data = new Bundle();
			data.putString(Global.STRPARA1, strQrcode);
			data.putInt(Global.INTPARA1, nWidthX);
			data.putInt(Global.INTPARA2,0);
			data.putInt(Global.INTPARA3, necl);
			WorkService.workThread.handleCmd(
					Global.CMD_POS_SETQRCODEV2, data);
				
		} else {
			Toast.makeText(cordova.getActivity(), Global.toast_notconnect, Toast.LENGTH_SHORT).show();
		}
	}

	public void connectionBT(String macAddress) {

		if(isConnectioned){
			return;
		}

		BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
		if (null == adapter) {
			return;
		}

		if (!adapter.isEnabled()) {
			if (adapter.enable()) {
				while (!adapter.isEnabled())
					;
				Log.v(TAG, "Enable BluetoothAdapter");
			} else {
				return;
			}
		}

		String address = macAddress;
		if (!BluetoothAdapter.checkBluetoothAddress(address)) {
			Toast.makeText(cordova.getActivity(), "Invalid address, eg:01:23:45:67:89:AB", Toast.LENGTH_LONG).show();
			return;
		}

		//dialog.setMessage(Global.toast_connecting + " " + address);
		//dialog.setIndeterminate(true);
		//dialog.setCancelable(false);
		//dialog.show();
		WorkService.workThread.connectBt(address);

	}

	/**
	 *
	 * @param args
	 * @param callbackContext
	 */
	private void getBoundDevices(JSONArray args, CallbackContext callbackContext){

		BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
		if (null == adapter) {
			return;
		}

		if (!adapter.isEnabled()) {
			if (adapter.enable()) {
				while (!adapter.isEnabled())
					;
				Log.v(TAG, "Enable BluetoothAdapter");
			} else {
				return;
			}
		}

		Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
		StringBuilder devices = new StringBuilder();
		if (pairedDevices.size() > 0) {
			for (BluetoothDevice device : pairedDevices) {
				String str = device.getName() + "|" + device.getAddress();
				if(devices.length() > 0)
					devices.append("\n");
				devices.append(str);
			}
		}

		PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, devices.toString());
		pluginResult.setKeepCallback(true);
		callbackContext.sendPluginResult(pluginResult);
	}

	class MHandler extends Handler {

		WeakReference<Activity> mActivity;

		MHandler(Activity activity) {
			mActivity = new WeakReference<Activity>(activity);
		}

		@Override
		public void handleMessage(Message msg) {
			Activity theActivity = cordova.getActivity();
			switch (msg.what) {
			/**
			 * DrawerService 的 onStartCommand会发送这个消息
			 */

			case Global.MSG_WORKTHREAD_SEND_CONNECTBTRESULT: {
				int result = msg.arg1;

				if(result == 1){
					isConnectioned = true;
				}else{
					isConnectioned = false;
				}

				Toast.makeText(theActivity, (result == 1) ? Global.toast_success : Global.toast_fail,
						Toast.LENGTH_SHORT).show();
				Log.v(TAG, "Connect Result: " + result);
				//theActivity.dialog.cancel();
				break;
			}

			case Global.CMD_POS_WRITERESULT: {
				int result = msg.arg1;
				Toast.makeText(theActivity, (result == 1) ? Global.toast_success : Global.toast_fail,
						Toast.LENGTH_SHORT).show();
				Log.v(TAG, "Result: " + result);
				break;
			}

			case Global.CMD_POS_SETBARCODERESULT: {
				int result = msg.arg1;
				Toast.makeText(theActivity, (result == 1) ? Global.toast_success : Global.toast_fail,
						Toast.LENGTH_SHORT).show();
				Log.v(TAG, "Result: " + result);
				break;
			}


			}
		}
	}

}
